package com.gui.lock.service.impl;

import com.gui.common.ResultStatus;
import com.gui.entity.Person;
import com.gui.lock.service.LockService;
import com.gui.lock.service.PersonService;
import com.gui.lock.utils.RedisLockProvider;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class LockServiceImpl implements LockService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private PersonService personService;

    @Autowired
    private RedissonClient redissonClient;

    private static final Logger logger = LoggerFactory.getLogger(LockServiceImpl.class);

    private static final String businessType = "test";

    @Override
    public String setnx() {
        RedisLockProvider lockProvider = new RedisLockProvider(stringRedisTemplate, businessType);
        boolean lockFlag = lockProvider.tryLock(50);
        if (!lockFlag) {
            logger.warn("Lock failed");
            return ResultStatus.FAIL;
        }
        logger.info("Lock successful");
        try {
            List<Person> personList = personService.queryAllPerson(new Person());
            List<String> personName = personList.stream().map(Person::getName).toList();
            logger.info("Person list: " + personName);
        } finally {
            lockProvider.unLock();
        }
        return ResultStatus.SUCCESS;
    }

    @Override
    public String redisson() {
        RLock lock = redissonClient.getLock("gui:" + businessType);
        try {
            boolean lockFlag = lock.tryLock(3, 120L, TimeUnit.SECONDS);
            if (!lockFlag) {
                logger.warn("Lock failed");
                return ResultStatus.FAIL;
            }
            logger.info("Lock successful");
            List<Person> personList = personService.queryAllPerson(new Person());
            List<String> personName = personList.stream().map(Person::getName).toList();
            logger.info("Person list: " + personName);
            return ResultStatus.SUCCESS;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}
